import datetime
from contextlib import asynccontextmanager

from fastapi import FastAPI, __version__ as fastapi_version
from fastapi.staticfiles import StaticFiles
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException
import uvicorn

from src.config.settings import get_settings, get_config_info
from src.constants import API_V1_PREFIX
from src.cores.exceptions import (
    CustomException,
    custom_exception_handler,
    http_exception_handler,
    validation_exception_handler,
    general_exception_handler,
)
from src.cores.database import db_manager
from src.cores.redis import redis_manager
from src.middlewares.cors import add_cors_middleware
from src.middlewares.logging import RequestLoggingMiddleware
from src.middlewares.auth import add_jwt_auth_middleware
from src.services.scheduler_service import scheduler_service
from src.utils.logger import app_logger as logger



@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    # 启动时的初始化操作
    import os

    process_id = os.getpid()
    logger.info(f"[进程 {process_id}] 应用启动中...")

    # 显示配置信息
    logger.info("=" * 50)
    logger.info("应用配置信息:")
    config_info = get_config_info()
    for key, value in config_info.items():
        logger.info(f"  {key}: {value}")
    logger.info("=" * 50)

    # 初始化数据库连接
    try:
        await db_manager.init_database()
    except Exception as e:
        logger.error(f"数据库连接失败: {e}")
        # 根据需要决定是否继续启动应用
        # raise e  # 如果数据库是必需的，取消注释这行

    try:
        # 初始化Redis连接
        await redis_manager.init_redis()
        logger.info("Redis初始化完成")
    except Exception as e:
        logger.error(f"Redis初始化失败: {e}")
        # 根据需要决定是否继续启动应用
        # raise e  # 如果Redis是必需的，取消注释这行

    # 启动定时任务服务
    try:
        scheduler_service.start()
        logger.info("定时任务服务已启动")
    except Exception as e:
        logger.error(f"定时任务服务启动失败: {e}")

    logger.info("应用启动完成")

    yield  # 应用运行期间

    # 关闭时的清理操作
    logger.info("应用关闭中...")

    # 清理操作
    try:
        scheduler_service.stop()
        logger.info("定时任务服务已停止")
    except Exception as e:
        logger.error(f"定时任务调度器停止失败: {e}")

    # 关闭数据库连接
    try:
        await db_manager.close_database()
        logger.info("数据库连接已关闭")
    except Exception as e:
        logger.error(f"数据库关闭失败: {e}")

    try:
        # 关闭Redis连接
        await redis_manager.close_redis()
        logger.info("Redis连接已关闭")
    except Exception as e:
        logger.error(f"Redis关闭失败: {e}")

    logger.info("应用关闭完成")


# 初始化 FastAPI 应用实例
config = get_settings()
app = FastAPI(
    title=config.APP_NAME,
    version=config.APP_VERSION,
    description=config.APP_DESCRIPTION,
    debug=config.DEBUG_MODE,
    docs_url="/docs" if config.DEBUG_MODE else None,
    redoc_url="/redoc" if config.DEBUG_MODE else None,
    lifespan=lifespan,
)

# 添加中间件
add_cors_middleware(app)
app.add_middleware(RequestLoggingMiddleware, log_level="INFO")

# 添加JWT鉴权中间件（可通过配置控制）
if config.ENABLE_JWT_AUTH:
    add_jwt_auth_middleware(app)
    logger.info("JWT鉴权中间件已启用")

# 添加异常处理器
app.add_exception_handler(CustomException, custom_exception_handler)  # type: ignore[arg-type]
app.add_exception_handler(HTTPException, http_exception_handler)  # type: ignore[arg-type]
app.add_exception_handler(RequestValidationError, validation_exception_handler)  # type: ignore[arg-type]
app.add_exception_handler(Exception, general_exception_handler)  # type: ignore[arg-type]

# 初始化数据库 (模板项目暂时注释)
# init_database_with_app(app)

# 挂载静态文件
app.mount(
    config.STATIC_URL,
    StaticFiles(directory=config.STATIC_DIR),
    name=config.STATIC_NAME,
)


@app.get("/", tags=["system"])
async def root() -> dict[str, str]:
    """根路径接口"""
    return {"message": "欢迎使用 ewentianshi API", "version": config.APP_VERSION}


@app.post("/", tags=["system"])
async def root_post() -> dict[str, str]:
    """根路径POST接口"""
    return {"message": "POST 请求成功", "version": config.APP_VERSION}


# 健康检查接口
@app.get("/health", tags=["system"])
async def health_check():
    """健康检查接口

    用于监控和负载均衡器检查服务状态
    """
    return {
        "status": "ok",
        "timestamp": datetime.datetime.now().isoformat(),
        "environment": "production" if not config.DEBUG_MODE else "development",
        "versions": {
            "app": config.APP_VERSION,
            "fastapi": fastapi_version,
        },
    }


# API V1 路由
from src.routers.api_router import api_router

# 挂载 V1 API 路由
app.include_router(api_router, prefix=API_V1_PREFIX)


# 启动应用（使用配置文件中的默认端口8088）
if __name__ == "__main__":
    config = get_settings()
    uvicorn.run("main:app", host=config.APP_HOST, port=config.APP_PORT, reload=True)
